#!/bin/sh -ef
#
# Copyright (C) 2003-2019  Dmitry V. Levin <ldv@altlinux.org>
# 
# The source package rebuild functions for the hsh-rebuild
#
# SPDX-License-Identifier: GPL-2.0-or-later
#

build_deps=
calc_check_install_build_deps()
{
	build_deps="$(wlimit_time_elapsed=$wlimit_time_short \
		      wlimit_time_idle=$wlimit_time_short \
		      wlimit_bytes_written=$wlimit_bytes_out \
		      chrootuid2 </dev/null)" &&
		verbose "$sname: fetched build dependencies." ||
		fatal "$sname: failed to fetch build dependencies."
	build_deps="$(printf %s "$build_deps" |LC_ALL=C grep -v '^rpmlib(' |LC_ALL=C tr -d [[:blank:]])"
	verbose "$sname: calculated build dependencies: $(printf %s "$build_deps" |tr -s '[:space:]' ' ')"

	local bad_deps
	if bad_deps="$(printf %s "$build_deps" |LC_ALL=C grep -v '^[[:alnum:]_/]')"; then
		fatal "$sname: invalid build dependencies: $(printf %s "$bad_deps" |tr -s '[:space:]' ' ')"
	fi

	if [ -n "$build_deps" ]; then
		hsh-install --no-lock \
			${quiet:+$quiet} \
			${verbose:+$verbose} \
			${number:+--number=$number} \
			${exclude_docs:+--excludedocs} \
			${hasher_priv_dir:+--hasher-priv-dir="$hasher_priv_dir"} \
			${known_mountpoints:+--mountpoints="$known_mountpoints"} \
			-- \
			"$workdir" $build_deps
	fi
} # calc_check_install_build_deps

create_filter_spec_buildreq()
{
	cat > "$chroot"/.host/filter_spec_buildreq <<\__EOF__
#!/bin/sh -ef
tr -s '[:blank:],' ' ' |
	while read REPLY; do
		set -- $REPLY
		while [ -n "$1" ]; do
			case "$2" in
				=|["<>"]|["<>"]=)
					[ -z "${1##*%*}" -o -z "${3##*%*}" ] ||
						printf %s\\n "$1 $2 $3"
					shift 2
					;;
				*)
					[ -z "${1##*%*}" ] ||
						printf %s\\n "$1"
					;;
			esac
			if ! shift; then
				echo >&2 "Invalid build dependencies: $REPLY"
				exit 1
			fi
		done
	done
__EOF__
	chmod 755 -- "$chroot"/.host/filter_spec_buildreq
}

make_srpm_from_pkgtar()
{
	# srcrpmdir: where to put the resulting srpm (on the "foreign" side).
	# The value must be quoted appropriately, so that it can be inserted
	# into shell code text (example: srcrpmdir='"$HOME/in/srpm"'):
	local srcrpmdir="${1-}" # optional; absent/empty means default
	local srpm_fast_payload=
	[ -n "$build_srpm_only" ] ||
		srpm_fast_payload="--define '_source_payload w1.gzdio'"
	if [ -z "$nodeps" ]; then
		# Calculate, check and install BuildRequires(pre) dependencies.
		create_filter_spec_buildreq
		create_entry_header
		cat >>"$entry" <<__EOF__
sed '/^buildrequires(pre):[[:space:]]*/I!d;s///' "\$HOME/in/spec"/* |
	/.host/filter_spec_buildreq
__EOF__
		calc_check_install_build_deps

		local buildreq_helper
		buildreq_helper="$(type -p hsh-buildreq-filter)" &&
			[ -r "$buildreq_helper" ] ||
			fatal 'hsh-buildreq-filter: Not available'

		install -p -m755 $verbose "$buildreq_helper" chroot/.host/hsh-buildreq-filter >&2

		# Calculate, check and install other build dependencies.
		create_entry_header
		cat >>"$entry" <<__EOF__
spec="\$(rpmbuild -bE \\
	--target="$(quote_shell "${target:-$def_target}")" \\
	$rpmargs \\
	--define "_specdir \$HOME/in/spec" \\
	--define "_sourcedir \$HOME/in/source" \\
	-- "\$HOME/in/spec"/*)" || exit
printf %s "\$spec" |
	/.host/hsh-buildreq-filter |
	/.host/filter_spec_buildreq
__EOF__
		calc_check_install_build_deps
	fi

	# At this stage, build environment should be ready for creating source rpm.
	create_entry_header
	cat >>"$entry" <<__EOF__
${srcrpmdir:+mkdir $verbose -m700 -- $srcrpmdir >&2}
SOURCE_DATE_EPOCH="\$(cat -- "\$HOME/in/SOURCE_DATE_EPOCH")"
export SOURCE_DATE_EPOCH
rpmbuild -bs --nodeps \\
	--target="$(quote_shell "${target:-$def_target}")" \\
	--define '_allow_undefined_macros 1' \\
	$rpmargs \\
	$srpm_fast_payload \\
	--define "_specdir \$HOME/in/spec" \\
	--define "_sourcedir \$HOME/in/source" \\
	${srcrpmdir:+--define '_srcrpmdir '$srcrpmdir} \\
	-- "\$HOME/in/spec"/*
# Once srpm is created, its sources are no longer needed.
rm -rf "\$HOME/in/spec" "\$HOME/in/source"
__EOF__
	wlimit_time_elapsed=$wlimit_time_long wlimit_time_idle=$wlimit_time_long wlimit_bytes_written=$wlimit_bytes_out \
	    chrootuid2 </dev/null &&
		verbose "$sname: created src.rpm file." ||
		fatal "$sname: failed to create src.rpm file"
} # make_srpm_from_pkgtar

source_package_type=
install_source_package()
{
	copy_chroot_incoming "$source"
	create_entry_header
	cat >>"$entry" <<__EOF__
mkdir -p $verbose -m700 -- "\$TMPDIR" >&2
rm -rf "\$HOME/in"
mkdir $verbose -m700 -- "\$HOME/in" >&2
# Check source file.
header="\$(od -A n -N 8 -t x1 -- "$(quote_shell "$sname")")"
case "\$header" in
	' ed ab ee db '??' '??' 00 01')
		mkdir $verbose -m700 -- "\$HOME/in/srpm" >&2
		install -pm644 $verbose "$(quote_shell "$sname")" "\$HOME/in/srpm/" >&2
		rpmquery --qf '%{buildtime}\\n' -p -- "$(quote_shell "$sname")" > "\$HOME/in/SOURCE_DATE_EPOCH"
		echo src.rpm
		exit 0
		;;
	' ed ab ee db '*)
		exit 0
		;;
esac
spec="\$(LC_ALL=C tar -tvf "$(quote_shell "$sname")" 2>/dev/null |
	sed '/^V---------[[:space:]]\+0\/0[[:space:]]\+0[[:space:]]\+[^[:space:]]\+[[:space:]]\+[^[:space:]]\+[[:space:]]\+/!d;s///;s/--Volume Header--\$//;q')"
if [ -n "\$spec" -a "\$spec" = "\${spec#*/}" ]; then
	mkdir $verbose -m700 -- "\$HOME/in/spec" "\$HOME/in/source" >&2
	tar $verbose -xf "$(quote_shell "$sname")" -C "\$HOME/in/source/" >&2
	mv $verbose "\$HOME/in/source/\$spec" "\$HOME/in/spec/" >&2
	date +%s -r "\$HOME/in/spec"/\$spec > "\$HOME/in/SOURCE_DATE_EPOCH"
	echo pkg.tar
	exit 0
fi
__EOF__
	source_package_type="$(wlimit_time_elapsed=$wlimit_time_short wlimit_time_idle=$wlimit_time_short wlimit_bytes_written=$wlimit_bytes_out \
		       chrootuid2 </dev/null)" &&
		verbose "$sname: installed source file." ||
		fatal "$sname: failed to install source file."
	purge_chroot_in
	case "$source_package_type" in
		src.rpm)
			;;
		pkg.tar)
			make_srpm_from_pkgtar '"$HOME/in/srpm"'
			;;
		*)
			fatal "$sname does not look like source package."
			;;
	esac
} # install_source_package

run_sisyphus_check()
{
	local dir="$1" no_check="$2" add_gpg="${3:-}"

	[ -n "$no_check" ] ||
		no_check="$no_sisyphus_check"
	[ "$no_check" != all ] || return 0

	if [ -n "$no_check" ]; then
		[ -z "$add_gpg" ] ||
			no_check="$no_check,gpg"
	else
		no_check=gpg
	fi

	create_entry_header
	cat >>"$entry" <<__EOF__
sisyphus_check --no-check="$(quote_shell "$no_check")" "$dir"
__EOF__

	wlimit_time_elapsed=$wlimit_time_long wlimit_time_idle=$wlimit_time_long wlimit_bytes_written=$wlimit_bytes_out \
	    chrootuid2 </dev/null &&
		verbose "$sname: sisyphus_check passed." ||
		fatal "$sname: sisyphus_check failed."
} # run_sisyphus_check

run_rebuild()
{
	create_entry_header
	cat >>"$entry" <<__EOF__
cd "\$HOME/in/srpm"
packager=\$(rpmquery -p --qf '%{PACKAGER}' *)
cat >>"\$HOME/.rpmmacros" <<EOF
%packager \$packager
EOF

target="$(quote_shell "${target:-$def_target}")" /.host/rebuild *
find "\$HOME/RPM/SRPMS/" -mindepth 1 -maxdepth 1 -type f -name \*.src.rpm -print0 |
	xargs -r0 mv -f $verbose --target-directory=/.out/ -- >&2
find "\$HOME/RPM/RPMS/" -mindepth 2 -maxdepth 2 -type f -name \*.rpm -print0 |
	xargs -r0 mv -f $verbose --target-directory=/.out/ -- >&2
__EOF__

	requested_mountpoints="$required_mountpoints" \
	    chrootuid2 </dev/null &&
		verbose "rebuild of \`$sname' complete." ||
		fatal "rebuild of \`$sname' failed."
} # run_rebuild
